package com.qixiucoding.read.noObjectReadExcel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description 无定义对象读取对象
 * @Author longhj
 * @Date 2022/11/04 星期五 23:47
 */
@Slf4j
public class NoModelDataListener extends AnalysisEventListener<Map<Integer, Object>> {


    /**
     * 表头Map，暂时存储表头信息
     */
    private Map<Integer, String> headMap;
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        this.headMap = headMap;
    }

    /**
     * 每隔5条存储数据库，实际使用中可以100条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    /**
     * 缓存行数大小
     */
    private List<Map<Integer, Object>> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
    /**
     * 解析结果List
     */
    private List<Map<String, Object>> resultDataList = new ArrayList<>();

    @Override
    public void invoke(Map<Integer, Object> data, AnalysisContext context) {
        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        cachedDataList.add(data);
        resultDataList.add(convertData(headMap, data));
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    private Map<String, Object> convertData(Map<Integer, String> headMap, Map<Integer, Object> data) {
        Map<String, Object> map = new HashMap<>();

        headMap.forEach((key, value) -> data.computeIfPresent(key, (k, v) -> {
            map.put(value, v);
            return v;
        }));
        return map;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        log.info("所有数据解析完成！");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据，开始存储数据库！", cachedDataList.size());
        log.info("存储数据库成功！");
    }
    /**
     * 返回标题的位置信息
     * @return
     */
    public Map<Integer, String> getHeadMap() {
        return headMap;
    }

    /**
     * 返回表头信息
     * @return
     */
    public List<String> getHeadList() {
        return new ArrayList<>(headMap.values());
    }

    public List<Map<Integer, Object>> getCachedDataList() {
        return cachedDataList;
    }

    public List<Map<String, Object>> getResultDataList() {
        return resultDataList;
    }
}

